package org.dingyom.user.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.dingyom.basics.constants.BaseConstants;
import org.dingyom.basics.constants.SmsContants;
import org.dingyom.basics.util.AjaxResult;
import org.dingyom.basics.util.SmsUtil;
import org.dingyom.basics.util.StrUtils;
import org.dingyom.basics.util.VerifyCodeUtils;
import org.dingyom.user.domain.Logininfo;
import org.dingyom.user.dto.SmsCodeDto;
import org.dingyom.user.mapper.LogininfoMapper;
import org.dingyom.user.service.IVerificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class VerificationServiceImpl implements IVerificationService {
    @Autowired
    private RedisTemplate redisTemplate;//注入redis
    @Autowired
    private LogininfoMapper logininfoMapper;
    @Override
    public String getImgCodeByKey(String key) {
        String code = VerifyCodeUtils.generateVerifyCode(4);//获取一个四位的验证码

        //存进redis 设置三分钟过期时间
        redisTemplate.opsForValue().set(BaseConstants.VERIFYCODE_KEY +key, code, 3, TimeUnit.MINUTES);
        //把验证码合成图片 并且加密为base64数据进行返回
        String base64Date = null;
        try {
            base64Date = VerifyCodeUtils.VerifyCode(100, 40, code);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return base64Date;
    }

    @Value("${sms.code.register.resend-time}")
    private Integer resendTime;//消息重发时间
    @Value("${sms.code.register.expire-time}")
    private Integer expireTime;//验证码过期时间
    @Override
    public AjaxResult sendSmsCode(SmsCodeDto dto) {
        String imgCodeKey = dto.getImgCodeKey();//图片验证码的key
        String imgCode = dto.getImgCode();//图片验证码
        String mobile = dto.getMobile();//电话号码
        //校验 判空 前端判断了 但是后端为了保险再判断一下
        if (StringUtils.isEmpty(mobile)||StringUtils.isEmpty(imgCode)||StringUtils.isEmpty(imgCodeKey)) {
            return AjaxResult.me().setSuccess(false).setMessage("非法请求，参数异常！");
        }
        //判断图片验证码是否正确
        String imgCodeOfRedis = (String)redisTemplate.opsForValue().get(BaseConstants.VERIFYCODE_KEY + imgCodeKey);
        //比对图片验证码 不区分大小写
        if (!imgCode.trim().equalsIgnoreCase(imgCodeOfRedis)){
            return AjaxResult.me().setSuccess(false).setMessage("请输入正确的图形验证码");
        }
        //判断手机号是否已经被注册 被注册就不能再注册
        Logininfo logininfo = logininfoMapper.loadByPhone(mobile);
        if (logininfo != null) {
            return AjaxResult.me().setSuccess(false).setMessage("该手机号已被注册，请登录后使用");
        }

        //判断短信验证码是否存在 redis中 保存格式设置成 code:time  验证码和生成时间
        String key = SmsContants.SMSCODE_KEY + mobile;
        String smsCodeOfRedis = (String)redisTemplate.opsForValue().get(key);
        String code = "";
        if (StringUtils.isEmpty(smsCodeOfRedis)) {//不存在就产生新的
            code = StrUtils.getRandomString(6);
        }else {//存在 就用存在的
            //判断两次发送验证码过了重发时间没 没过就可能是恶意请求 报错
            code = smsCodeOfRedis.split(":")[0];
            String time = smsCodeOfRedis.split(":")[1];
            if (System.currentTimeMillis()-new Date(Long.valueOf(time)).getTime() <= 60*1000*resendTime){//60*1000
                return AjaxResult.me().setSuccess(false).setMessage("非法请求，请勿乱搞！");
            }
        }

        //将验证码记录进redis
        redisTemplate.opsForValue().set(key, code+":"+System.currentTimeMillis(),expireTime, TimeUnit.MINUTES);

        //调用短信接口发送验证码 %s 占位符
        String content = String.format("您的验证码为%s，请在%s分钟之内使用！",code,expireTime);
//        SmsUtil.sendSms(mobile, content);

        System.out.println(content);
        return AjaxResult.me();
    }

    @Override
    public AjaxResult sendSmsCode2login(SmsCodeDto dto) {
        //校验 判空 前端判断了 但是后端为了保险再判    断一下
        String mobile = dto.getMobile();
        if (StringUtils.isEmpty(mobile)) {
            return AjaxResult.me().setSuccess(false).setMessage("非法请求，参数异常！");
        }

        //判断手机号对应的用户是否存在，没有注册就不存在
        Logininfo logininfo = logininfoMapper.loadByPhone(mobile);
        if (logininfo == null) {
            return AjaxResult.me().setSuccess(false).setMessage("该手机号未被注册，请先注册后使用");
        }
        //判断短信验证码是否存在 redis中 保存格式设置成 code:time  验证码和生成时间
        String key = SmsContants.SMSCODE_KEY + mobile;
        String smsCodeOfRedis = (String)redisTemplate.opsForValue().get(key);
        String code = "";
        if (StringUtils.isEmpty(smsCodeOfRedis)) {//不存在就产生新的
            code = StrUtils.getRandomString(6);
        }else {//存在 就用存在的
            //判断两次发送验证码过了重发时间没 没过就可能是恶意请求 报错
            code = smsCodeOfRedis.split(":")[0];
            String time = smsCodeOfRedis.split(":")[1];
            if (System.currentTimeMillis()-new Date(Long.valueOf(time)).getTime() <= 60*1000*resendTime){//60*1000
                return AjaxResult.me().setSuccess(false).setMessage("非法请求，请勿乱搞！");
            }
        }

        //将验证码记录进redis
        redisTemplate.opsForValue().set(key, code+":"+System.currentTimeMillis(),expireTime, TimeUnit.MINUTES);

        //调用短信接口发送验证码 %s 占位符
        String content = String.format("您的验证码为%s，请在%s分钟之内使用！",code,expireTime);
//        SmsUtil.sendSms(mobile, content);

        System.out.println(content);
        return AjaxResult.me();
    }

}
